package com.xyzq.cgate.core.plugin;

import com.baomidou.mybatisplus.toolkit.CollectionUtils;
import com.xyzq.cgate.common.constant.Constants;
import com.xyzq.cgate.common.entity.Plugin;
import com.xyzq.cgate.common.enums.MatchModeEnum;
import com.xyzq.cgate.common.enums.OpenStateEnum;
import com.xyzq.cgate.common.enums.PluginDetailEnum;
import com.xyzq.cgate.common.rule.custom.entity.ComplexRule;
import com.xyzq.cgate.common.rule.custom.entity.MatchCondition;
import com.xyzq.cgate.core.condition.strategy.ConditionMatchStrategyFactory;
import com.xyzq.cgate.core.cache.CacheManager;
import lombok.AllArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author chenchen
 * @date 2019/6/19 13:59
 */
@AllArgsConstructor
public abstract class AbstractPlugin implements IPlugin {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractPlugin.class);

    @Autowired
    private CacheManager cacheManager;

    protected abstract Mono<Void> doExecute(ServerWebExchange exchange, IPluginChain chain, ComplexRule rule);

    @Override
    public Mono<Void> execute(final ServerWebExchange exchange, final IPluginChain chain) {
        Plugin plugin = cacheManager.findPluginByName(getName());
        if(Objects.nonNull(plugin) && OpenStateEnum.OPEN.getCode().equals(plugin.getEnabled())) {
            List<ComplexRule> rules = cacheManager.findRuleByName(getName());
            if(CollectionUtils.isEmpty(rules)) {
                return chain.execute(exchange);
            }
            //rules有值，匹配条件取order第一个
            ComplexRule rule = filterRule(exchange, rules);
            if(Objects.isNull(rule)) {
                return chain.execute(exchange);
            } else {
                return doExecute(exchange, chain, rule);
            }
        } else {
            return chain.execute(exchange);
        }
    }

    private ComplexRule filterRule(ServerWebExchange exchange, List<ComplexRule> rules) {
        List<ComplexRule> filteredRules = rules.stream()
                .filter(r -> StringUtils.equals(r.getEnabled(), "" + OpenStateEnum.OPEN.getCode())) //过滤未开启的规则
                .filter(t -> {
                    MatchCondition requestCondition = (MatchCondition) exchange.getAttributes()
                            .get(Constants.REQUESTDTO);
                    MatchCondition ruleCondition = t.getMatchCondition();
                    return ConditionMatchStrategyFactory.of(MatchModeEnum.AND.getName())
                            .match(requestCondition, ruleCondition);
                })
                .collect(Collectors.toList());
        filteredRules.stream().sorted((m, n) -> {
            return m.getRuleOrder().compareTo(n.getRuleOrder());
        });
        return filteredRules.stream().findFirst().orElse(null);
    }


}
